home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 21
/
Cream of the Crop 21 (Terry Blount) (October 1996).iso
/
editor
/
gsar110.zip
/
GSAR.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-08-08
|
31KB
|
943 lines
/* gsar.c ***************************************** updated: 960808.09:28 TT
*
* Description : General Search And Replace utility (gsar)
* Author : Tormod Tjaberg & Hans Peter Verne
*
* Copyright (C) 1992-96 Tormod Tjaberg & Hans Peter Verne,
* This is free software, distributed under the terms of the
* GNU General Public License. For details see the file COPYING
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <limits.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "comp_dep.h"
#include "arg_func.h"
#include "gsar.h"
#define PROGRAM_NAME "gsar"
#define PROGRAM_VER "1.10"
/* Need setmode to turn my streams into binary Under MS-DOS
*/
#ifdef MSDOS
#include <fcntl.h>
#include <io.h>
#endif
#ifdef __UNIX__
#include <unistd.h>
#endif
/* Clever little option mimic wildcard expansion from
* shell ONLY available with the Zortech compiler ver 3.0x and upwards
* And in the Symantec compiler though it's been renamed
*/
#if defined(__ZTC__)
#include <dos.h>
#ifdef WILDCARDS
WILDCARDS
#endif
#ifdef EXPAND_WILDCARDS
EXPAND_WILDCARDS
#endif
#endif
/* Macro to determine if char is a path or drive delimiter
*/
#define IS_PATH_DELIM(c) ((c) == '\\' || (c) == ':' || (c) == '/')
#define LF 0xa
#define CR 0xd
#define SETVBUF_SIZ 0x4000
unsigned short nItemsSearch = 0;
unsigned short nItemsReplace = 0;
/* if the flag below is set we are not allowed to interrupt!
*/
#if defined(__UNIX__)
/* SunOS does not have this definition, so play it safe */
static int fCriticalPart = 0;
#else
static sig_atomic_t fCriticalPart = 0;
#endif
OUTPUT_CTRL Ctrl;
char **pFileList; /* list of files found on the command line */
char *pOutFile = NULL; /* current output file name make sure it's NULL */
char SearchBuf[PAT_BUFSIZ] = "";
char ReplaceBuf[PAT_BUFSIZ] = "";
char fSearchReplace = 0; /* default to a search initially */
char fFolded = 0; /* fold pattern ie. ignore case */
char fOverWrite = 0; /* overwrite input file */
char fForce = 0; /* force overwrite of existing output file */
char fBuffers = 0; /* just display search & replace buffers */
char fFilter = 0; /* make GSAR act like a filter */
/* Usage text and GNU licence information
*/
char *Usage[] =
{
PROGRAM_NAME ", ver " PROGRAM_VER " -- Copyright (C) 1992-96 Tormod Tjaberg & Hans Peter Verne",
"",
"Usage: gsar [options] [infile(s)] [outfile]",
"Options are:",
"-s<string> Search string ",
"-r[string] Replace string. Use '-r' to delete the search string from the file",
"-i Ignore case difference when comparing strings",
"-B just display search & replace Buffers",
"-f Force overwrite of an existing output file",
"-o Overwrite the existing input file",
"-c[n] show textual Context of match, 'n' is number of bytes in context",
"-x[n] show context as a heX dump, 'n' is number of bytes in context",
"-b display Byte offsets of matches in file",
"-l only List filespec and number of matches (default)",
"-h suppress display of filespec when displaying context or offsets",
"-du convert a DOS ASCII file to UNIX (strips carriage return)",
"-ud convert a UNIX ASCII file to DOS (adds carriage return)",
"-F 'Filter' mode, input from stdin and eventual output to stdout",
"-G display the GNU General Public Licence",
"",
"Ctrl characters may be entered by using a ':' in the string followed by the",
"ASCII value of the character. The value is entered using ':' followed by three",
"decimal digits or ':x' followed by two hex numbers. To enter ':' use '::'",
NULL
};
char *Licence[] =
{
"This program is free software; you can redistribute it and/or modify",
"it under the terms of the GNU General Public License as published by",
"the Free Software Foundation; either version 2 of the License, or",
"(at your option) any later version.",
"",
"This program is distributed in the hope that it will be useful,",
"but WITHOUT ANY WARRANTY; without even the implied warranty of",
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
"GNU General Public License for more details.",
"",
"You should have received a copy of the GNU General Public License",
"along with this program; if not, write to the Free Software",
"Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.",
NULL
};
/* Display the GNU General Public License
*/
void ShowLicence(void)
{
int i = 0;
while (Licence[i] != NULL)
{
fputs(Licence[i++], Ctrl.fpMsg);
fputc('\n', Ctrl.fpMsg);
}
}
/* Input : Message to be displayed with the format of standard printf
* Returns: Nothing, but instead it exits to operating system
*
* Terminate program, return to OS with a suitable return value
* exit() will close all open files. All fatal errors are written
* to stderr.
*/
void Abort(char *pMessage, ...)
{
va_list argp;
fprintf(stderr, "gsar: ");
va_start(argp, pMessage);
vfprintf(stderr, pMessage, argp);
va_end(argp);
fprintf(stderr, "\n");
exit(EXIT_FAILURE); /* exit & tell operating system that we've failed */
}
/* Ctrl-Break handler. Returns to operating system
*/
void CtrlBreak(int Val)
{
if (fCriticalPart)
return;
signal(SIGINT, SIG_IGN);
/* Before we die try to clean up as much as possible
* make sure we don't delete stdout...
*/
if (fSearchReplace && pOutFile != NULL && !fFilter)
remove(pOutFile);
exit(EXIT_FAILURE); /* exit & tell operating system that we've failed */
}
/* Input : pActStr - pointer to actual string which is to be duplicated
* Returns: pDupStr - pointer to malloc'd duplicate
* NULL - Out of memory
*
* Duplicates a string by malloc'ing and then doing a strcpy
*/
char *DupStr(char *pActStr)
{
register char *pDupStr;
pDupStr = (char *) malloc(strlen(pActStr) + 1);
if (pDupStr)
strcpy(pDupStr, pActStr);
return pDupStr;
}
/* Input : filespec - a filespec which contains a path and a filename
* Returns: savfilespec - pointer to malloc'd string with path
*
* Extracts the path from a filespec
*/
char *ExtractPathFromFSpec(register char *filespec)
{
register char *p;
register char *savfilespec;
savfilespec = DupStr(filespec); /* avoid destroying the original */
/* Start at end of string and back up till we find the beginning */
/* of the filename or a path. */
for (p = savfilespec + strlen(savfilespec);
p != savfilespec && !IS_PATH_DELIM(*(p - 1));
p--)
;
*p = '\0';
return savfilespec;
}
/* Input : pPath - which has to be properly terminated
* pPrefix - tmp filename prefix maximum 4 chars
* Returns: pointer to static buffer
* NULL - unable to generate tmp file name
*
* Generates a temporary filename by combining an optional path,
* a prefix ,a number between 0 & SHRT_MAX and the suffix '.tmp'.
*/
char *TmpName(char *pPath, char *pPrefix)
{
static char FileSpec[FILENAME_MAX ];
static char Seed = 0;
static short TmpNum;
char *pDigits;
unsigned short i;
struct stat buf;
*FileSpec = '\0'; /* Null terminate the buffer so strcat will always work */
if (!Seed) /* if first time through */
{
Seed++;
TmpNum = -1; /* since we increment this will make the first number 0000 */
}
if (pPath != NULL)
strcpy(FileSpec, pPath); /* first the path */
if (pPrefix != NULL)
strcat(FileSpec, pPrefix); /* then the prefix */
/* pointer to start of digits in filespec */
pDigits = FileSpec + strlen(FileSpec);
for (i = 0; i <= SHRT_MAX; i++) /* try SHRT_MAX times */
{
TmpNum++; /* TmpNum is static ! */
sprintf(pDigits, "%04x", TmpNum)